package com.kitty.game.zhenbao;

import com.kitty.common.cache.RedisService;
import com.kitty.common.db.Db4CommonService;
import com.kitty.common.utils.SpringUtils;
import com.kitty.common.thread.IdGenerator;
import com.kitty.game.ServerService;
import com.kitty.game.bag.message.RespIconCartoon;
import com.kitty.game.base.service.BagService;
import com.kitty.game.equip.message.RespNotifyMiscEx;
import com.kitty.game.equip.model.EquipField;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.service.EquipService;
import com.kitty.game.i18n.I18nId;
import com.kitty.game.identity.IdentityType;
import com.kitty.game.item.service.PetStoneService;
import com.kitty.game.market.MarketService;
import com.kitty.game.market.message.GoldStallRecord;
import com.kitty.game.market.message.RespMarketGoodCard;
import com.kitty.game.market.message.RespMarketPetCard;
import com.kitty.game.market.message.to.CardInfoParam;
import com.kitty.game.market.message.vo.GoldTransactionVo;
import com.kitty.game.market.model.Goods;
import com.kitty.game.market.model.MarketTransactionRecord;
import com.kitty.game.pet.message.RespPetHost;
import com.kitty.game.pet.model.Pet;
import com.kitty.game.pet.service.PetService;
import com.kitty.game.role.model.Role;
import com.kitty.game.role.service.RoleService;
import com.kitty.game.team.message.RespMsg;
import com.kitty.game.utils.AsktaoUtil;
import com.kitty.game.utils.NumberUtil;
import com.kitty.game.utils.TimeUtil;
import com.kitty.game.zhenbao.message.vo.MoneyGoods;
import com.kitty.game.zhenbao.model.Zhenbao;
import com.kitty.listener.EventDispatcher;
import com.kitty.listener.EventType;
import com.kitty.listener.event.RemovePetEvent;
import com.kitty.common.model.Reason;
import com.kitty.mina.cache.DataCache;
import com.kitty.mina.cache.SessionUtils;
import com.kitty.mina.message.MessagePusher;
import com.kitty.mina.task.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.mina.core.session.IoSession;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.json.Json;
import org.nutz.json.JsonFormat;
import org.nutz.lang.Strings;
import org.nutz.lang.util.NutMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.kitty.game.zhenbao.message.GoldStallGood;
import com.kitty.game.zhenbao.message.GoldStallGoodInfo;
import com.kitty.game.zhenbao.message.ReqGoldStallChangePrice;
import com.kitty.game.zhenbao.message.ReqGoldStallGoodsInfo;
import com.kitty.game.zhenbao.message.ReqGoldStallOpen;
import com.kitty.game.zhenbao.message.ReqGoldStallPutGoods;
import com.kitty.game.zhenbao.message.ReqGoldStallRemoveGoods;
import com.kitty.game.zhenbao.message.ResStallCashGoodsList;
import com.kitty.game.zhenbao.message.RespGoldStallMine;
import com.kitty.game.zhenbao.message.RespGuangtanList;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;


@Service
@Slf4j
public class ZhenbaoService {


    @Autowired
    PetService petService;
    @Autowired
    Dao dao;
    @Autowired
    EquipService equipService;
    @Autowired
    ServerService serverService;
    @Autowired
    BagService bagService;
    @Autowired
    RoleService roleService;
    @Autowired
    RedisService redisService;
    int neice;
    private Set<Integer> allowedMoneySet = new HashSet<>();

    boolean isClosed = false;
    private static int minLevel = 0;
    private static int minRechare = 0;

    private ConcurrentMap<Long, Zhenbao> allGoods = new ConcurrentHashMap<>();

    public void init() {
        Set<String> visited = new HashSet<>();
        List<Zhenbao> list = dao.query(Zhenbao.class, Cnd.NEW());
        for (Zhenbao goods : list) {
            goods.doAfterInit();
            equipService.fixEquip(goods.getRoleEquip());
            if (goods.getPet() != null) {
                String key = goods.getRoleId() + "_" + goods.getPet().getId();
                // 修复刷的宠物
                if (visited.contains(key)) {
                    goods.setDelete(true);
                    Db4CommonService.getInstance().add2Queue(goods);
                    log.error("删掉刷的珍宝,{}", key);
                    continue;
                }
                visited.add(key);
                if (!goods.getPet().isRepairedId()) {
//                    goods.getPet().setRepairedId(true);
                    int newId = SpringUtils.getIdentityService().getNextId(IdentityType.ROLE);
                    goods.getPet().setId(newId);
                }
            }
            allGoods.put(goods.getId(), goods);
        }
        allowedMoneySet.add(50000000);
        allowedMoneySet.add(100000000);
        allowedMoneySet.add(300000000);
        String jishi_state = DataCache.REDIS_DATA.get("zhenbao_state");
        minLevel = Integer.parseInt(DataCache.REDIS_DATA.get("jishi_min_level"));
        minRechare = Integer.parseInt(DataCache.REDIS_DATA.get("jishi_min_recharge"));
        if("1".equals(jishi_state)){
            isClosed = false;
        }else{
            isClosed = true;
        }
        if (serverService.getServer() != null && serverService.getServer().getId() == 1000){
            isClosed = true;
        }
    }


    public void queryTransactionRecord(Role role) {
        List<MarketTransactionRecord> records = role.getTransactionBox().getZhenBaoRecords();
        List<GoldTransactionVo> sellRecords = new ArrayList<>();
        List<GoldTransactionVo> buyRecords = new ArrayList<>();

        for (MarketTransactionRecord record : records) {
            GoldTransactionVo vo = GoldTransactionVo.valueOf(record);
            if (record.getType() > 0) {
                sellRecords.add(vo);
            } else {
                buyRecords.add(vo);
            }
        }

        GoldStallRecord response = new GoldStallRecord();
        response.setBuyList(buyRecords);
        response.setSellList(sellRecords);
        MessagePusher.pushMessage(role, response);
    }


    private boolean commonVerify(Role role) {
        if (isClosed) {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("珍宝维护中。");
            MessagePusher.pushMessage(role, respMsg);
            return false;
        }
        if(neice!=100){
            if (role.getTotalCharge() <= minRechare || role.getLevel() < minLevel){
                MessagePusher.pushMessage(role,new RespNotifyMiscEx("没有充值或等级不足，无法使用珍宝功能！！"));
                return false;
            }
        }
        if (role.isBanTrade()) {
            return false;
        }

        return true;
    }

    public void takeCash(Role role) {
        if (!commonVerify(role)) {
            return;
        }
        getGold(role);
    }

    public void getGold(Role role){
        long DBZhenbaoGold = role.getStallGold();
        if (DBZhenbaoGold <= 0) {
            MessagePusher.pushMessage(role,new RespNotifyMiscEx("珍宝中没有元宝。"));
            return;
        }
        int DBGold = role.getGold();
        if (DBGold >= 2000000000) {
            MessagePusher.pushMessage(role,new RespNotifyMiscEx("背包中元宝已满。"));
            return;
        }
        int tiqugold = 0;
        if (DBGold + DBZhenbaoGold > 2000000000) {
            tiqugold = 2000000000 - DBGold;
        } else {
            tiqugold = (int) DBZhenbaoGold;
        }

        log.error("roleId[{}] takeCash {}", role.getRoleId(), tiqugold);

        SpringUtils.getRoleService().addGold(role, tiqugold, Reason.ZHEN_BAO_CASH);

        role.setStallGold(DBZhenbaoGold - tiqugold);
        role.save();
        roleService.updateRoleGoldAndSiver(role);

        MessagePusher.pushMessage(role, new RespNotifyMiscEx("你成功提取了" + AsktaoUtil.getMoneyFormat(tiqugold) + "#n元宝！"));
        sendGoodsList(role);
    }

    /**
     * 购买
     */
    public synchronized void buyGoods(Role role, long goodsId, int price) {
        if (!commonVerify(role)) {
            return;
        }
        Zhenbao zhenbao = allGoods.get(goodsId);
        if (zhenbao == null) {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("物品信息不存在。");
            MessagePusher.pushMessage(role, respMsg);
            return;
        }
        if (zhenbao.getPrice() != price) {
            log.error("roleId[{}] buyGoods {} price {} req {}", role.getRoleId(), zhenbao.getName(), zhenbao.getPrice(), price);
            return;
        }
        int DBGold = role.getGold();
        if (DBGold < zhenbao.getPrice()) {
            log.error("roleId[{}] buyGoods {} price {} owned {}", role.getRoleId(), zhenbao.getName(), zhenbao.getPrice(), DBGold);
            return;
        }
        if (zhenbao.getRoleId() == role.getUid()) {
            log.error("roleId[{}] buyGoods {} self", role.getRoleId(), zhenbao.getName());
            return;
        }
        if (zhenbao.getShowEndTime().after(new Date())) {
            log.error("roleId[{}] buyGoods {} showTime{} now {}", role.getRoleId(), zhenbao.getName(), zhenbao.getShowEndTime().getTime(), System.currentTimeMillis());
            return;
        }
        if (zhenbao.getEndTime().before(new Date())) {
            log.error("roleId[{}] buyGoods {} endTime{} now {}", role.getRoleId(), zhenbao.getName(), zhenbao.getEndTime().getTime(), System.currentTimeMillis());
            return;
        }

        if (zhenbao.getType1().equals("宠物")) {
            if (SpringUtils.getPetService().isEquippedFull(role)) {
                MessagePusher.pushMessage(role, new RespMsg("你的宠物栏已满。"));
                return;
            }
            SpringUtils.getRoleService().subtractGold(role, zhenbao.getPrice(), Reason.ZHEN_BAO_BUY);
            role.save();
            roleService.updateRoleGoldAndSiver(role);
            Pet pet = zhenbao.getPet();
            role.getPetBox().addNewPet(pet);
            pet.setHostId(role.getRoleId());
            pet.setHostName(role.getName());

            petService.addLimitTimeDay(pet, 3);
            petService.loadPet(role, pet);

            RespIconCartoon respIconCartoon = new RespIconCartoon();
            respIconCartoon.setType((short) 2);
            respIconCartoon.setName(pet.getName());
            if (pet.getItype() != 0) {
                respIconCartoon.setParam(pet.getRankItem() + "");
            } else {
                respIconCartoon.setParam(pet.getIcon() + "");
            }
            MessagePusher.pushMessage(role, respIconCartoon);
            MessagePusher.pushMessage(role, new RespNotifyMiscEx("你花费了#R" + zhenbao.getPrice() + "#n金元宝，购买了一只#Y"
                    + pet.getName() + "#n。"));
            log.error("roleId[{}] buy pet {} price {} owner uid{} petId[{}] ", role.getRoleId(), zhenbao.getName(), zhenbao.getPrice(), zhenbao.getRoleId(), pet.getId());
        } else if (zhenbao.getType1().equals("金钱")) {
            SpringUtils.getRoleService().subtractGold(role, zhenbao.getPrice(), Reason.ZHEN_BAO_BUY);
            role.save();
            roleService.updateRoleGoldAndSiver(role);
            SpringUtils.getRoleService().addMoney(role, Integer.parseInt(zhenbao.getName()));
            roleService.updateRoleMoney(role);
            MessagePusher.pushMessage(role, new RespNotifyMiscEx("你花费了#R" + zhenbao.getPrice() + "#n金元宝，获得了#Y"
                    + zhenbao.getName() + "金币#n。"));

            log.error("roleId[{}] buy money {} price {} owner uid{} money[{}] ", role.getRoleId(), zhenbao.getName(), zhenbao.getPrice(), zhenbao.getRoleId(), zhenbao.getName());
        } else {
            short pos = bagService.getPos(role, false);
            if (pos <= 0) {
                MessagePusher.pushMessage(role, new RespMsg("你的包裹已满，还是整理后再来吧。"));
                return;
            }
            RoleEquip roleEquip = zhenbao.getRoleEquip();
            if (roleEquip == null) {
                return;
            }
            SpringUtils.getRoleService().subtractGold(role, zhenbao.getPrice(), Reason.ZHEN_BAO_BUY);
            role.save();
            roleService.updateRoleGoldAndSiver(role);

            roleEquip.setPosition(pos);
            roleEquip.setRoleId(role.getRoleId());
            equipService.addRoleEquipLimitTimeDay(roleEquip, 3);
            equipService.add(role, roleEquip);

            // 入包动画
            RespIconCartoon respIconCartoon = new RespIconCartoon();
            respIconCartoon.setName(roleEquip.getName());
            respIconCartoon.setParam(roleEquip.getId() + "");
            MessagePusher.pushMessage(role, respIconCartoon);
            equipService.refreshRoleEquip(role, roleEquip);
            MessagePusher.pushMessage(role, new RespNotifyMiscEx("你花费了#R" + zhenbao.getPrice() + "#n金元宝购买了一件#Y"
                    + zhenbao.getName() + "#n。"));
            log.error("roleId[{}] buy item {} price {} owner uid{} equipId[{}]", role.getRoleId(), zhenbao.getName(), zhenbao.getPrice(), zhenbao.getRoleId(), roleEquip.getId());
        }



        zhenbao.setDelete(true);
        Db4CommonService.getInstance().add2Queue(zhenbao);
        allGoods.remove(goodsId);

        // 给买方钱
        Role seller = SpringUtils.getPlayerService().getPlayerBy(zhenbao.getRoleId());
        if (SpringUtils.getRoleService().isOnline(seller)) {
            ThreadLocalUtil.addLocalTask(seller, () -> addMoneyToSeller(seller, zhenbao));
        } else {
            addMoneyToSeller(seller, zhenbao);
        }

        MarketTransactionRecord buyRecord = MarketTransactionRecord.valueOf(zhenbao);
        role.getTransactionBox().addZhenBaoRecord(buyRecord);

        IoSession session = SessionUtils.getSessionBy(role.getUid());
        if (session == null) {
            return;
        }
        Object object = session.getAttribute("zhenbao_list");
        if (object == null) {
            return;
        }
        ReqGoldStallOpen reqGoldStallOpen = (ReqGoldStallOpen) object;
        queryGoodsList(role, reqGoldStallOpen);
    }

    private void addMoneyToSeller(Role seller, Goods zhenBao) {
        seller.setStallGold(seller.getStallGold() + zhenBao.getPrice());
        MarketTransactionRecord sellRecord = MarketTransactionRecord.valueOf(zhenBao);
        sellRecord.setType((byte) 1);
        seller.getTransactionBox().addZhenBaoRecord(sellRecord);
        seller.save();

        log.error("addMoneyToSeller {} goods[{}] [{}] price {} nowMoney {}", seller.getRoleId(),
                zhenBao.getId(), zhenBao.getName(), zhenBao.getPrice(), seller.getStallGold());
    }


    /**
     * 改价
     *
     * @param session
     * @param req
     */
    public synchronized void updatePrice(IoSession session, ReqGoldStallChangePrice req) {
        Role role = SessionUtils.getRoleBySession(session);
        if (!commonVerify(role)) {
            return;
        }
        if (req.getPrice() < 0) {
            return;
        }
        String goodsId = req.getId();
        if (Strings.isEmpty(goodsId)) {
            return;
        }
        Zhenbao zhenbao = allGoods.get(Long.parseLong(goodsId));
        if (zhenbao == null) {
            return;
        }

        if (zhenbao.getRoleId() != role.getUid()) {
            return;
        }

        long now = System.currentTimeMillis();
        if (now - zhenbao.getLastUpdatePrice() < TimeUtil.ONE_DAY) {
            return;
        }

        int oldPrice = zhenbao.getPrice();

        if (zhenbao.getType1().equals("金钱")) {
            if (req.getPrice() > NumberUtil.intValue(zhenbao.getName()) / 10000d * 1.2) {
                log.error("moneyUpShell error price, roleId[{}] sold {} price {}", role.getRoleId(), NumberUtil.intValue(zhenbao.getName(), req.getPrice()));
                return;
            }
        }

//        zhenbao.setPrice(req.getPrice());

        log.error("roleId[{}] update price {}", role.getRoleId(), oldPrice, zhenbao.getPrice());
        Db4CommonService.getInstance().add2Queue(zhenbao);

        sendGoodsList(role);
    }


    /**
     * 打开珍宝界面
     */
    public void sendGoodsList(Role role) {
        if (isClosed) {
            MessagePusher.pushMessage(role, new RespMsg("珍宝维护中..."));
            return;
        }
        if(neice!=100){
            if (role.getTotalCharge() <= minRechare || role.getLevel() < minLevel){

                MessagePusher.pushMessage(role,new RespNotifyMiscEx("没有充值或等级不足，无法使用珍宝功能！！"));
                return ;
            }
        }

        RespGoldStallMine respGoldStallMine = new RespGoldStallMine();
        respGoldStallMine.setStallTotalNum(SpringUtils.getBean(MarketService.class).getMaxStallNum(role));
        respGoldStallMine.setSellCash(role.getStallGold() + "");
        respGoldStallMine.setGoods(new ArrayList<>());
        MessagePusher.pushMessage(role, respGoldStallMine);
        List<Zhenbao> goods = queryMyGoods(role);
        for (Zhenbao zhenbao : goods) {
            GoldStallGood goldStallGood = new GoldStallGood();
            if (zhenbao.getShowEndTime().after(new Date())) {
                goldStallGood.setStartTime(new Long(zhenbao.getStartTime().getTime() / 1000).intValue());
                goldStallGood.setEndTime(new Long(zhenbao.getShowEndTime().getTime() / 1000).intValue());
            } else {
                goldStallGood.setStartTime(new Long(zhenbao.getShowEndTime().getTime() / 1000).intValue());
                goldStallGood.setEndTime(new Long(zhenbao.getEndTime().getTime() / 1000).intValue());
            }
            goldStallGood.setName(zhenbao.getName());
            goldStallGood.setId(zhenbao.getMianbanId() + "");
            goldStallGood.setPrice(zhenbao.getPrice());
            goldStallGood.setInit_price(zhenbao.getPrice());
            goldStallGood.setLevel(zhenbao.getLevel());
            if (zhenbao.getShowEndTime().after(new Date())) {
                goldStallGood.setStatus((short) 1);// 公示
            } else if (zhenbao.getEndTime().before(new Date())) {
                goldStallGood.setStatus((short) 3);// 超时
            } else {
                goldStallGood.setStatus((short) 2);// 在售
            }
            if (zhenbao.getType1().equals("宠物")) {
                Pet pet = zhenbao.getPet();
                if (pet == null) {
                    continue;
                }
                goldStallGood.setLevel((short) 0);
                goldStallGood.setPetLevel(pet.getLevel());
                NutMap nutMap = NutMap.NEW();
                nutMap.setv("enchant", pet.getEnchant());
                nutMap.setv("rank", pet.getType());
                nutMap.setv("mount_type", pet.getItype());
                if (pet.getMagRebuildLevel() == 0 && pet.getPhyRebuildLevel() == 0) {
                    nutMap.setv("rebuild_level", 0);// 0未强化 1强化
                } else {
                    nutMap.setv("rebuild_level", 1);// 0未强化 1强化
                }
                nutMap.setv("eclosion", pet.getEclosion());//2羽化
                goldStallGood.setExtra(Json.toJson(nutMap, JsonFormat.compact()));
                goldStallGood.setStall_item_type((byte) 2);
            } else if (zhenbao.getType1().equals("金钱")) {
                goldStallGood.setStall_item_type((byte) 1);
            }

            respGoldStallMine.getGoods().add(goldStallGood);
        }
        MessagePusher.pushMessage(role, respGoldStallMine);

    }

    /**
     * 宠物摆上摊
     */
    private void petUpShell(ReqGoldStallPutGoods reqGoldStallPutGoods, Role role, int marketRent) {
        Pet pet = petService.getPetById(reqGoldStallPutGoods.getPos(), role);
        if (pet == null) {
            return;
        }
        if (pet.getType() <= 2 && pet.getItype() == 0) {
            return;
        }
        if (pet.getItype() >= 1 && pet.getRank() < 6) {
            return;
        }
        int time = pet.getLimitTime();
        if (time < 0) {
            time = -time;
            if (System.currentTimeMillis() / 1000 < time) {
                return;
            }
        }
        int DBMoney = role.getMoney();
        roleService.subtractMoney(role, marketRent);
        roleService.updateRoleMoney(role);
        role.getPetBox().removePet(pet);
        /** 产生一个移除宠物事件 */
        EventDispatcher.getInstance().fireEvent(new RemovePetEvent(EventType.REMOVE_PET, role, pet));

        log.error("roleId[{}] upShell pet {} name{} price {}", role.getRoleId(), pet.getId(), pet.getName(), reqGoldStallPutGoods.getPrice());

        //消失宠物
        RespPetHost respPetHost = new RespPetHost();
        respPetHost.setPetId(pet.getId());
        MessagePusher.pushMessage(role, respPetHost);

        Zhenbao zhenbao = new Zhenbao();
        zhenbao.setPrice(reqGoldStallPutGoods.getPrice());
        zhenbao.setLevel(pet.getLevel());
        zhenbao.setXiangxin(pet.getPolar());

        zhenbao.setRoleId(role.getUid());
        zhenbao.setName(pet.getName());
        zhenbao.setId(IdGenerator.getNextId());
        zhenbao.setType1("宠物");
        if (pet.getItype() == 1 || pet.getItype() == 2) {
            zhenbao.setType2("精怪/御灵");
        } else if (pet.getType() == 2) {
            zhenbao.setType2("普通");
        } else if (pet.getType() == 3) {
            zhenbao.setType2("变异");
        } else if (pet.getType() == 4) {
            zhenbao.setType2("神兽");
        }
        zhenbao.setPet(pet);

        addGoods(zhenbao);
        role.save();

        sendGoodsList(role);
    }

    /**
     * 珍宝上架装备
     *
     * @param zhenbao
     * @param nutMap
     */
    private void initEquipAttr(Zhenbao zhenbao, NutMap nutMap) {
        if (zhenbao.getType1().equals("装备") || zhenbao.getType1().equals("未鉴定装备")) {
            if (nutMap.getInt("menpaiYaoqiu") == 1) {
                zhenbao.setType2("全部武器");
            } else if (nutMap.getInt("menpaiYaoqiu") == 2) {
                zhenbao.setType2("全部武器");
            } else if (nutMap.getInt("menpaiYaoqiu") == 3) {
                zhenbao.setType2("全部武器");
            } else if (nutMap.getInt("menpaiYaoqiu") == 4) {
                zhenbao.setType2("全部武器");
            } else if (nutMap.getInt("menpaiYaoqiu") == 5) {
                zhenbao.setType2("全部武器");
            } else {
                zhenbao.setType2("全部防具");
            }
            zhenbao.setLevel((short) nutMap.getInt("level1"));
        }
    }


    /**
     * 上架物品
     */
    public synchronized void upShell(Role role, ReqGoldStallPutGoods req) {
        if (!commonVerify(role)) {
            return;
        }
        List<Zhenbao> myGoods = queryMyGoods(role);
        int size = myGoods.size();
        if (size >= SpringUtils.getBean(MarketService.class).getMaxStallNum(role)) {
            return;
        }

        if (req.getPrice() < 0) {
            return;
        }

        int marketRent = (int) Math.ceil(req.getPrice() * 100);
        marketRent = Math.min(marketRent, 5000000);
        marketRent = Math.max(marketRent, 500000);
        int DBMoney = role.getMoney();
        if (DBMoney < marketRent) {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("你的金钱不足！请到积分商城购买");
            MessagePusher.pushMessage(role, respMsg);
            return;
        }
        if (serverService.getServer().getId() == 10000){
            MessagePusher.pushMessage(role,new RespNotifyMiscEx("跨服试道中，不能上架珍宝"));
            return;
        }
        if (req.getPrice() <=12000  && req.getType() != 3){
            MessagePusher.pushMessage(role,new RespNotifyMiscEx("物品价格不能低于12000！！"));
            return;
        }
        if (req.getType() == 1) {
            itemUpShell(req, role, marketRent);
        } else if (req.getType() == 2) {
            // 宠物摆摊
            petUpShell(req, role, marketRent);
        } else if (req.getType() == 3) {
            moneyUpShell(req, role, marketRent);
        }
    }

    private void itemUpShell(ReqGoldStallPutGoods req, Role role, int marketRent) {
        int pos = req.getPos();
        RoleEquip roleEquip = equipService.getRoleEquipByPos(role, (short) pos);
        if (roleEquip == null) {
            return;
        }

        // 带皇冠的法宝
        boolean isBetterFabao = roleEquip.getType().equals("法宝") && roleEquip.queryLevel() >= 10;
        if (roleEquip.queryUpgradeLevel() < 6 && !roleEquip.getType().equals("高级首饰")) {
            if (!isBetterFabao) {
                return;
            }
        }

        if (roleEquip.isLimit()) {
            return;
        }

        int DBMoney = role.getMoney();
        roleService.subtractMoney(role, marketRent);
        roleService.updateRoleMoney(role);

        Zhenbao zhenbao = new Zhenbao();
        zhenbao.setId(IdGenerator.getNextId());
        zhenbao.setName(roleEquip.getName());
        zhenbao.setRoleEquip(roleEquip);
        NutMap nutMap = equipService.getRoleEquipBaiscInfo(roleEquip);
        zhenbao.setLevel((short) nutMap.getInt("level1"));
        zhenbao.setPrice(req.getPrice());
        zhenbao.setRoleId(role.getUid());
        zhenbao.setType1(roleEquip.getType());

        equipService.delRoleEquip(roleEquip, role);

        addGoods(zhenbao);

        zhenbao.initSubType(nutMap);
        initEquipAttr(zhenbao, nutMap);

        log.error("roleId[{}] upShell item id{} name {} price {}", role.getRoleId(), roleEquip.getId(), roleEquip.getName(), req.getPrice());

        sendGoodsList(role);
        role.save();
    }

    private void moneyUpShell(ReqGoldStallPutGoods req, Role role, int marketRent) {
        int soldMoney = req.getPos();
        if (role.getMoney() < soldMoney + marketRent) {
            return;
        }
        if (!allowedMoneySet.contains(soldMoney)) {
            return;
        }

        int price = req.getPrice();
        if (price > soldMoney / 10000d * 1.2) {
            log.error("moneyUpShell error price, roleId[{}] sold {} price {}", role.getRoleId(), soldMoney, price);
            return;
        }

        int DBMoney = role.getMoney();
        roleService.subtractMoney(role, marketRent + soldMoney);
        roleService.updateRoleMoney(role);

        Zhenbao zhenbao = new Zhenbao();
        zhenbao.setId(IdGenerator.getNextId());
        zhenbao.setName(String.valueOf(soldMoney));
        zhenbao.setPrice(req.getPrice());
        zhenbao.setRoleId(role.getUid());
        zhenbao.setType1("金钱");

        log.error("roleId[{}] upShell money {} rent {} price {}", role.getRoleId(), soldMoney, marketRent, req.getPrice());

        addGoods(zhenbao);
        sendGoodsList(role);
        role.save();
    }

    public synchronized void queryCashList(Role role) {
        List<MoneyGoods> goodsList = new ArrayList<>();

        Map<Integer, Integer> minPrice = new HashMap<>();
        for (Map.Entry<Long, Zhenbao> entry : allGoods.entrySet()) {
            Zhenbao goods = entry.getValue();
            if ("金钱".equals(goods.getType1())) {
                if (goods.getRoleId() == role.getUid()) {
                    // 跳过自己上架的
                    continue;
                }
                if (goods.getShowEndTime().after(new Date())) {
                    continue;
                }
                if (goods.getEndTime().before(new Date())) {
                    continue;
                }
                int money = Integer.parseInt(goods.getName());
                int low = minPrice.getOrDefault(money, Integer.MAX_VALUE);
                if (goods.getPrice() < low) {
                    minPrice.put(money, goods.getPrice());
                }
            }
        }

        for (Map.Entry<Integer, Integer> entry : minPrice.entrySet()) {
            MoneyGoods goods2 = new MoneyGoods();
            goods2.setName(String.valueOf(entry.getKey()));
            goods2.setPrice(entry.getValue());
            goodsList.add(goods2);
        }

        ResStallCashGoodsList response = new ResStallCashGoodsList();
        response.setGoodsList(goodsList);
        MessagePusher.pushMessage(role, response);
    }

    public synchronized void buyCash(Role role, int money, int price) {
        Zhenbao target = null;
        for (Map.Entry<Long, Zhenbao> entry : allGoods.entrySet()) {
            Zhenbao goods = entry.getValue();
            if ("金钱".equals(goods.getType1())) {
                if (goods.getRoleId() == role.getUid()) {
                    // 跳过自己上架的
                    continue;
                }
                if (goods.getShowEndTime().after(new Date())) {
                    continue;
                }
                if (goods.getEndTime().before(new Date())) {
                    continue;
                }
                if (goods.getPrice() == price && goods.getName().equals("" + money)) {
                    target = goods;
                    break;
                }
            }
        }
        if (target == null) {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("道具被抢购完啦");
            MessagePusher.pushMessage(role, respMsg);
            return;
        }
        buyGoods(role, target.getId(), target.getPrice());

        log.error("roleId[{}] buy money {} price {} owner uid{}", role.getRoleId(), target.getName(), target.getPrice(), target.getRoleId());
        queryCashList(role);
    }

    private void addGoods(Zhenbao zhenbao) {
        zhenbao.setStartTime(new Date());
        zhenbao.setShowEndTime(new Date(System.currentTimeMillis() + 5 * TimeUtil.ONE_MINUTE));
        zhenbao.setNumber(1);
        zhenbao.setEndTime(new Date(System.currentTimeMillis() + 3 * TimeUtil.ONE_DAY));

        allGoods.put(zhenbao.getId(), zhenbao);
        Db4CommonService.getInstance().add2Queue(zhenbao);
    }

    /**
     * 货物详情
     *
     * @param session
     * @param reqGoldStallGoodsInfo
     */
    public void goodsInfo(IoSession session, ReqGoldStallGoodsInfo reqGoldStallGoodsInfo) {
        if (isClosed) {
            MessagePusher.pushMessage(session, new RespMsg("珍宝维护中..."));
            return;
        }
        Role role = SessionUtils.getRoleBySession(session);
        if(neice!=100){
            if (role.getTotalCharge() <= minRechare || role.getLevel() < minLevel){

                MessagePusher.pushMessage(role,new RespNotifyMiscEx("没有充值或等级不足，无法使用珍宝功能！！"));
                return ;
            }
        }

        if (role == null) {
            return;
        }
        long goodsId = Long.parseLong(reqGoldStallGoodsInfo.getId());
        Zhenbao zhenbao = allGoods.get(goodsId);
        if (zhenbao == null) {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("物品信息不存在。");
            MessagePusher.pushMessage(session, respMsg);
            return;
        }
        if (zhenbao.getType1().equals("宠物")) {
            Pet pet = zhenbao.getPet();
            List<EquipField> stoneFields = SpringUtils.getBean(PetStoneService.class).getStoneExtraFields(pet);
            RespMarketPetCard respMarketPetCard = new RespMarketPetCard();
            if (zhenbao.getShowEndTime().after(new Date())) {
                respMarketPetCard.setEndTime(new Long(zhenbao.getShowEndTime().getTime() / 1000).intValue());
            } else {
                respMarketPetCard.setEndTime(new Long(zhenbao.getEndTime().getTime() / 1000).intValue());
            }
            respMarketPetCard.setGoodId(zhenbao.getMianbanId());
            respMarketPetCard.setList(new ArrayList<>());
            respMarketPetCard.getList().addAll(pet.getAllFields());
            MessagePusher.pushMessage(session, respMarketPetCard);
            return;
        } else if (zhenbao.getType1().equals("金钱")) {
            return;
        }

        List<EquipField> list = equipService.transferList(zhenbao.getRoleEquip().getFields());
        RespMarketGoodCard respMarketGoodCard = new RespMarketGoodCard();
        respMarketGoodCard.setList(list);
        respMarketGoodCard.setId(reqGoldStallGoodsInfo.getId());
        if (zhenbao.getShowEndTime().after(new Date())) {
            respMarketGoodCard.setTime(new Long(zhenbao.getShowEndTime().getTime() / 1000).intValue());
        } else {
            respMarketGoodCard.setTime(new Long(zhenbao.getEndTime().getTime() / 1000).intValue());
        }
        MessagePusher.pushMessage(session, respMarketGoodCard);
    }

    private List<Predicate<Goods>> filterConditions(String condition1, String condition2, String condition3, int type) {
        List<Predicate<Goods>> result = new ArrayList<>();
        switch (condition1) {
            case "高级首饰": {
                result.add(goods -> goods.getType1().equals("高级首饰"));
                result.add(goods -> goods.getType2().equals(condition2));
                int type3 = Integer.parseInt(condition3);
                result.add(goods -> goods.getLevel() == type3);
                break;
            }
            case "装备": {
                result.add(goods -> goods.getType1().equals("装备"));
                result.add(goods -> goods.getType2().equals(condition2));
                int type3 = Integer.parseInt(condition3);
                result.add(goods -> goods.getLevel() >= type3 && goods.getLevel() <= type3 + 9);
                break;
            }
            case "法宝":
                result.add(goods -> goods.getType1().equals("法宝"));
                result.add(goods -> goods.getName().equals(condition2));
                break;
            case "宠物":
                result.add(goods -> goods.getType1().equals("宠物"));
                result.add(goods -> goods.getType2().equals(condition2));
                break;
        }
        result.add(goods -> goods.getEndTime().getTime() > new Date().getTime());

        if (type == 1) {
            result.add(goods -> goods.getShowEndTime().getTime() > new Date().getTime());
        } else {
            result.add(goods -> goods.getShowEndTime().getTime() < new Date().getTime());
        }


        return result;
    }

    /**
     * @param req
     */
    public void queryGoodsList(Role role, ReqGoldStallOpen req) {
        if (isClosed) {
            MessagePusher.pushMessage(role, new RespMsg("珍宝维护中..."));
            return;
        }
        if(neice!=100){
            if (role.getTotalCharge() <= minRechare || role.getLevel() < minLevel){

                MessagePusher.pushMessage(role,new RespNotifyMiscEx("没有充值或等级不足，无法使用珍宝功能！！"));
                return ;
            }
        }
        IoSession session = SessionUtils.getSessionBy(role.getUid());
        if (session == null) {
            return;
        }
        session.setAttribute("zhenbao_list", req);
        RespGuangtanList respBaitanList = new RespGuangtanList();
        respBaitanList.setPath_str(req.getType());
        String[] conditionArray = req.getType().split("_");
        String condition1 = conditionArray.length > 0 ? conditionArray[0] : null;
        String condition2 = conditionArray.length > 1 ? conditionArray[1] : null;
        String condition3 = conditionArray.length > 2 ? conditionArray[2] : null;

        String[] pageParams = req.getPage().split(";");
        int type = Integer.parseInt(pageParams[1]);
        int pageIndex = Integer.parseInt(pageParams[0]);
        String sortKey = pageParams.length > 3 ? pageParams[3] : "price";
        int sortType = pageParams.length > 2 ? Integer.parseInt(pageParams[2]) : 1;

        List<Predicate<Goods>> conditions = filterConditions(condition1, condition2, condition3, type);
        Stream<Zhenbao> stream = allGoods.values().stream();

        for (Predicate<Goods> predicate : conditions) {
            stream = stream.filter(predicate);
        }

        List<Zhenbao> targetGoods = stream.collect(Collectors.toList());
        int countPerPage = 8;
        int maxPage = (int) Math.ceil((double) targetGoods.size() / countPerPage);

        targetGoods.sort((o1, o2) -> {
            if (sortKey.equals("start_time")) {
                if (1 == sortType) {
                    // 升序
                    return o1.getStartTime().compareTo(o2.getStartTime());
                }
                return o2.getStartTime().compareTo(o1.getStartTime());
            }
            if (1 == sortType) {
                // 升序
                return o1.getPrice() - o2.getPrice();
            }
            return o2.getPrice() - o1.getPrice();
        });


        pageIndex = Math.max(1, pageIndex);
        pageIndex = Math.min(pageIndex, maxPage);


        respBaitanList.setTotalPage((short) maxPage);
        respBaitanList.setPageIndex((short) pageIndex);
        respBaitanList.setSell_stage((byte) (type == 1 ? 1 : 2));
        List<GoldStallGoodInfo> list = new ArrayList<>();
        respBaitanList.setList(list);

        int startIndex = (pageIndex - 1) * countPerPage - 1;
        startIndex = Math.max(0, startIndex);
        int endIndex = startIndex + countPerPage;
        endIndex = Math.min(endIndex, targetGoods.size());
        targetGoods = targetGoods.subList(startIndex, endIndex);
        for (Zhenbao zhenbao : targetGoods) {
            GoldStallGoodInfo goldStallGoodInfo = new GoldStallGoodInfo();
            goldStallGoodInfo.setName(zhenbao.getName());
            goldStallGoodInfo.setId(zhenbao.getMianbanId() + "");
            if (type == 1) {
                goldStallGoodInfo.setStartTime(new Long(zhenbao.getStartTime().getTime() / 1000).intValue());
                goldStallGoodInfo.setEndTime(new Long(zhenbao.getShowEndTime().getTime() / 1000).intValue());
                goldStallGoodInfo.setStatus((short) 1);
            } else {
                goldStallGoodInfo.setStartTime(new Long(zhenbao.getShowEndTime().getTime() / 1000).intValue());
                goldStallGoodInfo.setEndTime(new Long(zhenbao.getEndTime().getTime() / 1000).intValue());
                goldStallGoodInfo.setStatus((short) 2);
            }
            goldStallGoodInfo.setPrice(zhenbao.getPrice());
            goldStallGoodInfo.setLevel(zhenbao.getLevel());
            goldStallGoodInfo.setPetLevel((short) 0);
            if (zhenbao.getType1().equals("宠物")) {
                Pet pet = zhenbao.getPet();
                if (pet == null) {
                    continue;
                }
                goldStallGoodInfo.setLevel((short) 0);
                goldStallGoodInfo.setPetLevel(pet.getLevel());
                NutMap nutMap = NutMap.NEW();
                nutMap.setv("enchant", pet.getEnchant());
                nutMap.setv("rank", pet.getType());
                nutMap.setv("mount_type", pet.getItype());
                if (pet.getMagRebuildLevel() == 0 && pet.getPhyRebuildLevel() == 0) {
                    nutMap.setv("rebuild_level", 0);// 0未强化 1强化
                } else {
                    nutMap.setv("rebuild_level", 1);// 0未强化 1强化
                }
                nutMap.setv("eclosion", pet.getEclosion());//2羽化
                goldStallGoodInfo.setPetInfo(Json.toJson(nutMap, JsonFormat.compact()));
            }
            list.add(goldStallGoodInfo);
        }
        MessagePusher.pushMessage(session, respBaitanList);
    }


    /**
     * 撤摊
     *
     * @param session
     * @param reqGoldStallRemoveGoods
     */
    public synchronized void removeGoods(IoSession session, ReqGoldStallRemoveGoods reqGoldStallRemoveGoods) {
        Role role = SessionUtils.getRoleBySession(session);
        if (!commonVerify(role)) {
            return;
        }
        short pos = bagService.getPos(session, false);
        if (pos <= 0) {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("你的包裹已满。");
            MessagePusher.pushMessage(session, respMsg);
            return;
        }
        long goodsId = Long.parseLong(reqGoldStallRemoveGoods.getId());
        Zhenbao zhenbao = allGoods.get(goodsId);
        if (zhenbao == null) {
            return;
        }
        if (zhenbao.getRoleId() != role.getId()) {
            log.error("roleId[{}] steal goodsId {}", role.getRoleId(), zhenbao.getId());
            return;
        }
        allGoods.remove(goodsId);
        zhenbao.setDelete(true);
        Db4CommonService.getInstance().add2Queue(zhenbao);

        // 物品放回原主人背包
        if (zhenbao.getType1().contains("宠物")) {
            Pet pet = zhenbao.getPet();
            log.error("roleId[{}] removeGoods pet {} petName {}", role.getRoleId(), pet.getId(), pet.getName());
            role.getPetBox().addNewPet(pet);
            petService.loadPet(role, pet);
        } else if (zhenbao.getType1().equals("金钱")) {
            int soldMoney = Integer.parseInt(zhenbao.getName());
            SpringUtils.getRoleService().addMoney(role, soldMoney);
            roleService.updateRoleMoney(role);
            log.error("roleId[{}] removeGoods money {}", role.getRoleId(), zhenbao.getName());
        } else {
            // 刷新背包
            RoleEquip roleEquip = zhenbao.getRoleEquip();
            roleEquip.setPosition(pos);
            equipService.add(role, roleEquip);

            equipService.refreshRoleEquip(role, roleEquip);

            log.error("roleId[{}] removeGoods item {} {}", role.getRoleId(), roleEquip.getId(), roleEquip.getName());
        }

        role.save();

        sendGoodsList(role);
    }


    private List<Zhenbao> queryMyGoods(Role role) {
        List<Zhenbao> result = new ArrayList<>();
        for (Map.Entry<Long, Zhenbao> entry : allGoods.entrySet()) {
            Zhenbao goods = entry.getValue();
            if (goods.getRoleId() == role.getUid()) {
                result.add(goods);
            }
        }
        return result;
    }

    public Zhenbao getZhenbaoById(long goodsId) {
        return allGoods.get(goodsId);
    }

    /**
     * 查看名片
     */
    public void viewZhenbaoCard(Role role, String status, String string) {
        if (isClosed) {
            RespMsg respMsg = new RespMsg();
            respMsg.setMsg("珍宝维护中...");
            MessagePusher.pushMessage(role, respMsg);
            return;
        }
        if(neice!=100){
            if (role.getTotalCharge() <= minRechare || role.getLevel() < minLevel){

                MessagePusher.pushMessage(role,new RespNotifyMiscEx("没有充值或等级不足，无法使用珍宝功能！！"));
                return ;
            }
        }
        String[] statusArray = status.split("=");
        long gid = Long.parseLong(statusArray[1].split("\\|")[0]);

        Goods selectGoods = allGoods.get(gid);
        /**找不到时*/
        if (selectGoods == null) {
            MessagePusher.notify2Player(role, I18nId.PMT_1319);
            return ;
        }

        CardInfoParam cardInfoParam = Json.fromJson(CardInfoParam.class, string);

        byte type = (byte) (selectGoods.getShowEndTime().getTime() > new Date().getTime() ? 1 : 2);
        String sortKey = (type == 1 ? cardInfoParam.getShow_sort().getKey() : cardInfoParam.getSell_sort().getKey());
        byte sortType = (type == 1 ? cardInfoParam.getShow_sort().getType() : cardInfoParam.getSell_sort().getType());

        /**筛选出与所选同一分类中的所有物品并排序*/
        List<Goods> targetGoods = filterAndSortGoods(selectGoods.getType1(), selectGoods.getType2(), String.valueOf(selectGoods.getLevel()), type, sortKey, sortType);

        int index = 0;
        for (Goods goods : targetGoods) {
            if (goods.getId() == selectGoods.getId()) {break;}
            index ++;
        }
        /**从1开始计算，所以需要加1*/
        index += 1;
        int countPerPage = 8;
        int pageIndex = index /countPerPage + ((index % countPerPage == 0) ? 0 : 1);
        int maxPage = (int) Math.ceil((double) targetGoods.size() / countPerPage);
        pageIndex = Math.max(1, pageIndex);
        pageIndex = Math.min(pageIndex, maxPage);

        /**截出所选物品的那一页所有物品*/
        targetGoods = subSelectedPageGoods(targetGoods, countPerPage, pageIndex);

        RespGuangtanList response = new RespGuangtanList();
        response.setSort_key(sortKey);
        response.setIs_descending(sortType);
        String pathStr = getSelectedPathStr(selectGoods);
        response.setPath_str(pathStr);
        response.setTotalPage((short) maxPage);
        List<GoldStallGoodInfo> list = getItemList(type, targetGoods);
        response.setList(list);
        response.setPageIndex((short) pageIndex);
        response.setSell_stage(type);
        response.setSelect_gid(String.valueOf(gid));

        MessagePusher.pushMessage(role, response);
    }

    /**
     * 筛选出与所选同一分类中的所有物品并排序
     */
    private List<Goods> filterAndSortGoods(String condition1, String condition2, String condition3, byte type, String sortKey, byte sortType) {
        List<Predicate<Goods>> conditions = filterConditions(condition1, condition2, condition3, type);
        Stream<Zhenbao> stream = allGoods.values().stream();

        for (Predicate<Goods> predicate : conditions) {
            stream = stream.filter(predicate);
        }


        List<Goods> targetGoods = stream.collect(Collectors.toList());
        targetGoods.sort((o1, o2) -> {
            if (sortKey.equals("start_time")) {
                if (1 == sortType) {
                    // 升序
                    return o1.getStartTime().compareTo(o2.getStartTime());
                }
                return o2.getStartTime().compareTo(o1.getStartTime());
            }
            if (1 == sortType) {
                // 升序
                return o1.getPrice() - o2.getPrice();
            }
            return o2.getPrice() - o1.getPrice();
        });
        return targetGoods;
    }

    /**
     * 截出所选物品的那一页所有物品
     */
    private List<Goods> subSelectedPageGoods(List<Goods> targetGoods, int countPerPage, int pageIndex) {
        int startIndex = (pageIndex - 1) * countPerPage - 1;
        startIndex = Math.max(0, startIndex);
        int endIndex = startIndex + countPerPage;
        endIndex = Math.min(endIndex, targetGoods.size());
        targetGoods = targetGoods.subList(startIndex, endIndex);
        return targetGoods;
    }

    /**
     * 获得所选的便签路径
     */
    private String getSelectedPathStr(Goods selectGoods) {
        StringBuilder sb = new StringBuilder();
        if (StringUtils.isNotEmpty(selectGoods.getType1())) {
            sb.append(selectGoods.getType1());
        }
        if (StringUtils.isNotEmpty(selectGoods.getType2())) {
            if (sb.length() > 0) {sb.append("_");}
            sb.append(selectGoods.getType2());
        }
        if (StringUtils.isNotEmpty(selectGoods.getType3())) {
            if (sb.length() > 0) {sb.append("_");}
            sb.append(selectGoods.getType3());
        }
        return sb.toString();
    }


    private List<GoldStallGoodInfo> getItemList(byte type, List<Goods> targetGoods) {
        List<GoldStallGoodInfo> list = new ArrayList<>();
        for (Goods goods : targetGoods) {
            GoldStallGoodInfo goldStallGoodInfo = new GoldStallGoodInfo();
            goldStallGoodInfo.setName(goods.getName());
            goldStallGoodInfo.setId(goods.getMianbanId() + "");
            if (type == 1) {
                goldStallGoodInfo.setStartTime(new Long(goods.getStartTime().getTime() / 1000).intValue());
                goldStallGoodInfo.setEndTime(new Long(goods.getShowEndTime().getTime() / 1000).intValue());
                goldStallGoodInfo.setStatus((short) 1);
            } else {
                goldStallGoodInfo.setStartTime(new Long(goods.getShowEndTime().getTime() / 1000).intValue());
                goldStallGoodInfo.setEndTime(new Long(goods.getEndTime().getTime() / 1000).intValue());
                goldStallGoodInfo.setStatus((short) 2);
            }
            goldStallGoodInfo.setPrice(goods.getPrice());
            goldStallGoodInfo.setLevel(goods.getLevel());
            goldStallGoodInfo.setPetLevel((short) 0);
            if (goods.getType1().equals("宠物")) {
                Pet pet = goods.getPet();
                if (pet == null) {
                    continue;
                }
                goldStallGoodInfo.setLevel((short) 0);
                goldStallGoodInfo.setPetLevel(pet.getLevel());
                NutMap nutMap = NutMap.NEW();
                nutMap.setv("enchant", pet.getEnchant());
                nutMap.setv("rank", pet.getType());
                nutMap.setv("mount_type", pet.getItype());
                if (pet.getMagRebuildLevel() == 0 && pet.getPhyRebuildLevel() == 0) {
                    nutMap.setv("rebuild_level", 0);// 0未强化 1强化
                } else {
                    nutMap.setv("rebuild_level", 1);// 0未强化 1强化
                }
                nutMap.setv("eclosion", pet.getEclosion());//2羽化
                goldStallGoodInfo.setPetInfo(Json.toJson(nutMap, JsonFormat.compact()));
            }
            list.add(goldStallGoodInfo);
        }
        return list;
    }
}
